<?php

namespace app\api\model;

use app\admin\model\vip\Code;
use app\exceptions\ApiException;
use ba\Exception;
use EasyWeChat\Factory;
use think\facade\Db;
use think\Model;

/**
 * Banner
 */
class Pay
{
    // 表名

    protected $expire_type = [1 => 1, 2 => 182, 3 => 365];


    public function payVipCard($params){
        $member_id = $params['member_id'];
        $vip_card_id = $params['vip_card_id'] ?? 0;

        $validate = new \app\api\validate\PayVipCard();
        if (!$validate->scene('pay')->check($params)) {
            throw new ApiException($validate->getError());
        }

        //查询会员卡
        $vip_card = (new VipCard())->where(['id' => $vip_card_id,'status' => 1])->find();
        if(!$vip_card) throw  new ApiException('数据异常');

        //查询卡密是否存在
        $vip_code = (new Code())->where(['admin_id' => 1,'vip_card_id' => $vip_card_id,'status'=>0,'is_freeze'=>0])->count();
        if($vip_code == 0) throw  new ApiException('无库存，请联系管理员');

        //查询用户信息
        $member = (new Member())->where(['id' => $member_id])->find();
        if(!$member) throw new ApiException('用户不存在');
        if(!$member['username'] || !$member['id_number']) throw new ApiException('请先实名认证');


        //判断是否买过
        if($vip_card_id == 2) {
            $member_vip_card = (new MemberVipCard())->where(['member_id' => $member_id,'vip_card_id' => 2])->find();
            if($member_vip_card) throw new ApiException('一个账号只能购买一次体验卡');
        }

        //查询是否已经购买改 景区/民宿会员卡
        $member_vip_card = (new MemberVipCard())->where(['vip_type' => $vip_card['type'],'member_id' => $member,'status' => 1 ])->find();
        if($member_vip_card) throw new ApiException('您已拥有该类型的会员卡，请前往升级页面,进行升级或续费');


        $order_no = $this->build_order_no('VC');
        //创建订单
        $data = [
           'out_trade_no' => $order_no,
            'member_id' => $member_id,
            'vip_card_id' => $vip_card_id,
            'price' => $vip_card['price'],
            'user_name' => $params['user_name'],
            'user_phone' => $params['user_phone'],
            'address' => $params['address'],
            'vip_code' => '',
        ];

        try {
            Db::startTrans();
            (new VipOrder())->save($data);
            //执行支付
            $title = "购买会员卡".$vip_card['price'];
            $config = $this->toPay($title,$order_no,$vip_card['price'],'vipCardCallback',$member['openid']);
            Db::commit();
            return api_message($config);
        }catch (Exception $e){
            Db::rollBack();
            throw new ApiException($e->getMessage());
        }

    }




    public function upgradeVipCard($params){
        $card_id = $params['vip_card_id'] ?? 0;
        $member_id = $params['member_id'];

        //获取需要升级的卡片信息
        $vip_card = (new VipCard())->where(['id' => $card_id])->find();
        if(!$vip_card) throw new ApiException('会员不存在');

//        //查询是否有库存
//        $vip_code = (new Code())->where(['admin_id' => 1,'vip_card_id' => $vip_card['id'],'status'=>0,'is_freeze'=>0])->count();
//        if($vip_code == 0) throw  new ApiException('无库存，请联系管理员');
        //查询用户开通的该类型的会员卡
        $member_vip_card = (new MemberVipCard())->where(['member_id' => $member_id,'vip_type' => $vip_card['type'],'status'=>1])->find();
        if(!$member_vip_card) throw new ApiException('您未开通会员卡，无法升级');

        //查询用户开通的会员卡
        $user_vip_card = (new VipCard())->where(['id' => $member_vip_card['vip_card_id']])->find();
        if($vip_card['level'] < $user_vip_card['level']) throw new ApiException('该会员卡类型低于您当前已开通的会员卡等级，无法进行升级');

        if($user_vip_card['use_type'] != $vip_card['use_type']){
            $text = $user_vip_card['use_type'] == 1 ? "次数卡":'时效卡';
            throw new ApiException('您的会员卡为'.$text.'，请选择相应类型的会员');
        }

        $member = (new Member())->where(['id' => $member_id])->find();

        $order_no = $this->build_order_no('VU');
        $data = [
            'out_trade_no' => $order_no,
            'member_id' => $member_id,
            'new_vip_card_id' => $card_id,
            'old_vip_card_id' => $member_vip_card['vip_card_id'],
            'vip_code' => $member_vip_card['vip_code'],
        ];

        if($vip_card['id'] == $member_vip_card['vip_card_id']){
            //续费
            $data['type'] = 1;
            $data['price'] = $vip_card['price'];
            $title = "续费".$vip_card['name'];
        }else{
            //升级
            $data['type'] = 2;
            $data['price'] = $this->upgrade($vip_card,$user_vip_card,$member_vip_card);
            $title = "升级".$vip_card['name'];
        }
        try {
            Db::startTrans();
            (new VipUpgrade())->save($data);
            //执行支付
            $config = $this->toPay($title,$order_no,$data['price'],'vipUpgradeCallback',$member['openid']);
            Db::commit();
            return api_message($config);
        }catch (Exception $e){
            Db::rollBack();
            throw new ApiException($e->getMessage());
        }
    }



    //计算补差价
    public function upgrade($new_vip_card,$old_vip_card,$member_vip_card){
        //计算当前日期到会员卡到期时间
        $day = $this->calculateDaysDifferenceFromTimestamp($member_vip_card['expire_time']);
        //计算升级的会员卡每天多少钱
        if($new_vip_card['use_type'] == 1){
            //次数
            $old_day_price =  bcdiv( $old_vip_card['price'], $old_vip_card['nums'],2);
        }else{
            //时效
            $old_day_price =  bcdiv( $old_vip_card['price'], $this->expire_type[$old_vip_card['expire_type']],2);
        }
        return round($new_vip_card['price'] - $old_day_price * $day, 2);
    }


    public function calculateDaysDifferenceFromTimestamp($timestamp) {
        // 获取当前时间的时间戳
        $currentTimestamp = time();

        // 计算两个时间戳之间的差值
        $difference = $timestamp - $currentTimestamp ;

        // 将差值转换为天数（秒数除以每天的秒数）
        $daysDifference = floor($difference / (60 * 60 * 24));

        return $daysDifference;
    }





    public function build_order_no($prefix)
    {
        return $prefix . date('ymd') . substr(
                implode(null, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))),
                0,
                8
            );
    }


    public function toPay($body, $out_trade_no, $pay_amount, $callback, $openid)
    {
//        $pay_amount = 0.01;
        $app = Factory::payment(config('wechat.wechat_pay'));
        $jssdk = $app->jssdk;
        $data = [
            'body' => $body,
            'out_trade_no' => $out_trade_no,
            'total_fee' => $pay_amount * 100,
            'notify_url' => env('domain.api_url') . '/index.php/call/pay/' . $callback, // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
            'openid' => $openid, //
        ];
        \think\facade\Log::info(json_encode($data));
        $result = $app->order->unify($data);
        if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
            $config = $jssdk->sdkConfig($result['prepay_id']); // 返回数组
            if (isset($config['timestamp'])) { // 检查timestamp是否存在
                $config['timeStamp'] = $config['timestamp']; // 复制timestamp的值到timeStamp
                unset($config['timestamp']); // 删除timestamp键
            }
            return $config;
        } else {
            throw new ApiException($result['err_code_des']);
        }
    }


    public function refund($transaction_id,$out_trade_no,$price,$refund_price)
    {
        $app = Factory::payment(config('wechat.wechat_pay'));
        $res = $app->refund->byTransactionId(
            $transaction_id,
            $out_trade_no,
            $price * 100,
            $refund_price * 100
        );
        if ($res['return_code'] == 'SUCCESS' && $res['result_code'] == 'SUCCESS') {
            return true;
        }

        throw new ApiException($res['err_code_des']);
    }

}
